﻿using System;
using JetBrains.Annotations;

namespace MugenMvvmToolkit.Infrastructure
{
    /// <summary>
    ///     Represents the action token.
    /// </summary>
    public sealed class ActionToken : IDisposable
    {
        #region Fields

        private readonly object _locker;
        private Action<object> _action;
        private readonly object _state;

        #endregion

        #region Constructors

        /// <summary>
        ///     Initializes a new instance of the <see cref="ActionToken" /> class.
        /// </summary>
        public ActionToken([NotNull]Action action)
            : this(o => action(), null)
        {
            Should.NotBeNull(action, "action");
        }

        /// <summary>
        ///     Initializes a new instance of the <see cref="ActionToken" /> class.
        /// </summary>
        public ActionToken([NotNull]Action<object> action, object state)
        {
            Should.NotBeNull(action, "action");
            _action = action;
            _state = state;
            _locker = new object();
        }

        #endregion

        #region Implementation of IDisposable

        /// <summary>
        ///     Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            Action<object> action;
            using (DeadLockDetector.Lock(_locker))
            {
                if (_action == null) return;
                action = _action;
                _action = null;
            }
            action(_state);
        }

        #endregion
    }
}